# import json
# import pickle
# import base64
# from http.cookiejar import Cookie
#
# from django.http import JsonResponse
# from django.shortcuts import render
# from django.views import View
# # Create your views here.
# from django_redis import get_redis_connection
# from goods.models import SKU
#
#
# class CartsView(View):
#     @staticmethod
#     def get(request):
#         """获取购物车记录"""
#         nginx_url = 'http://192.168.19.131:8888/'
#         user = request.user
#         if user.is_authenticated:
#             # 登录
#             redis_conn = get_redis_connection('cart')
#             cart_selecteds = redis_conn.smembers(f'cart_selected_{user.id}')
#             # 获取所有的key sku id
#             cart_skus = redis_conn.hgetall(f'cart_{user.id}')
#             cart_skus_li = []
#             for cart_sku, cart_skus_value in cart_skus.items():
#                 try:
#                     sku = SKU.objects.get(id=cart_sku)
#                 except Exception:
#                     return JsonResponse({'code': 400,
#                                  'message': '获取商品失败'})
#
#                 sku_data = {
#                     "id": sku.id,
#                     "name": sku.name,
#                     "price": sku.price,
#                     "default_image_url": ''.join([nginx_url, sku.default_image.name]),
#                     # 注意 如果此处不 转换为int 类型,  在前端会默认是str  str的 count +1 就是拼接
#                     "count": int(cart_skus_value),
#                     "selected": cart_sku in cart_selecteds
#                 }
#                 cart_skus_li.append(sku_data)
#
#             return JsonResponse({"code": 0,
#                                 "message": "OK",
#                                 "cart_skus": cart_skus_li})
#         else:
#             # 未登录
#             cart_data_str = request.COOKIES.get('cart_data')
#             cart_skus_li = []
#
#             if cart_data_str:
#                 # 如果购物车里面已经有数据了  先解析出来
#                 cart_data = pickle.loads(base64.b64decode(cart_data_str))
#             else:
#                 return JsonResponse({'code': 0,
#                                      'message': 'OK',
#                                      'count': []})
#
#             for cart_sku in cart_data:
#                 try:
#                     sku = SKU.objects.get(id=cart_sku)
#                 except Exception:
#                     return JsonResponse({'code': 400,
#                                  'message': '获取商品失败'})
#
#                 sku_data = {
#                     "id": sku.id,
#                     "name": sku.name,
#                     "price": sku.price,
#                     "default_image_url": ''.join([nginx_url, sku.default_image.name]),
#                     "count": cart_data[cart_sku]['count'],
#                     "selected": cart_data[cart_sku]['selected']
#                 }
#                 cart_skus_li.append(sku_data)
#             return JsonResponse({'code': 0,
#                                 'message': 'OK',
#                                 'cart_skus': cart_skus_li})
#
#     @staticmethod
#     def post(request):
#         """添加商品到购物车"""
#         req_data = json.loads(request.body)
#         sku_id = req_data.get('sku_id')
#         count = req_data.get('count')
#         selected = req_data.get('selected', True)
#
#         if not all([sku_id, count]):
#             return JsonResponse({'code': 400,
#                                  'message': '缺少必传参数'})
#
#         try:
#             count = int(count)
#         except Exception:
#             return JsonResponse({'code': 400,
#                                  'message': 'count参数有误'})
#         if count <= 0:
#             return JsonResponse({'code': 400,
#                                  'message': 'count参数有误'})
#         try:
#             SKU.objects.get(id=sku_id)
#         except SKU.DoesNotExist:
#             return JsonResponse({'code': 400,
#                                  'message': '商品不存在'})
#
#         user = request.user
#         if user.is_authenticated:
#             # 登录 存储到redis中
#             # 连接redis
#             try:
#                 redis_conn = get_redis_connection('cart')
#                 redis_conn.hincrby(f'cart_{user.id}', sku_id, count)
#                 if selected:
#                     redis_conn.sadd(f'cart_selected_{user.id}', sku_id)
#             except:
#                 return JsonResponse({'code': 400,
#                                      'message': '连接数据库失败'})
#
#             return JsonResponse({'code': 0,
#                                 'message': 'OK',
#                                 'count': count})
#         else:
#             # 未登录 存储到cookie中
#             # 首先要先获取cookie
#             cart_data_str = request.COOKIES.get('cart_data')
#             if cart_data_str:
#                 # 如果购物车里面已经有数据了  先解析出来
#                 cart_data = pickle.loads(base64.b64decode(cart_data_str))
#             else:
#                 cart_data = {}
#
#             if sku_id in cart_data:
#                 count1 = cart_data[sku_id]['count'] + count
#                 cart_data[sku_id]['count'] = count1
#             else:
#                 cart_data[sku_id] = {"count": count, "selected": selected}
#             response = JsonResponse({'code': 0,
#                                      'message': 'OK',
#                                      'count': count})
#             saved_data = base64.b64encode(pickle.dumps(cart_data)).decode()
#
#             response.set_cookie('cart_data', saved_data, max_age=3600*24*14)
#
#             return response
#
#     @staticmethod
#     def put(request):
#         """修改购物车商品"""
#         req_data = json.loads(request.body.decode())
#         sku_id = req_data.get('sku_id')
#         count = req_data.get('count')
#         selected = req_data.get('selected')
#
#         if not all([sku_id, count]):
#             return JsonResponse({'code': 0,
#                                  'message': '缺少必传参数!'})
#         try:
#             count = int(count)
#         except Exception:
#             return JsonResponse({'code': 400,
#                                  'message': 'count参数有误'})
#         if count <= 0:
#             return JsonResponse({'code': 400,
#                                  'message': 'count参数有误'})
#
#         try:
#             SKU.objects.get(id=sku_id)
#         except Exception:
#             return JsonResponse({'code': 400,
#                                  'message': '商品不存在'})
#
#         user = request.user
#         if user.is_authenticated:
#             # 登录 存储到redis中
#             # 连接redis
#             try:
#                 redis_conn = get_redis_connection('cart')
#                 redis_conn.hset(f'cart_{user.id}', sku_id, count)
#                 if selected:
#                     redis_conn.sadd(f'cart_selected_{user.id}', sku_id)
#                 else:
#                     redis_conn.srem(f'cart_selected_{user.id}', sku_id)
#
#             except Exception:
#                 return JsonResponse({'code': 400,
#                                      'message': '连接数据库失败'})
#
#             return JsonResponse({'code': 0,
#                                  'message': 'OK',
#                                  'cart_sku': {
#                                     "sku_id": sku_id,
#                                     "count": int(count),
#                                     "selected": selected
#                                   }})
#         else:
#             # 未登录 存储到cookie中
#             # 首先要先获取cookie
#             try:
#                 cart_data_str = request.COOKIES.get('cart_data')
#             except Exception:
#                 return JsonResponse({'code': 400,
#                                      'message': '连接数据库失败'})
#
#             cart_data = pickle.loads(base64.b64decode(cart_data_str))
#
#             cart_data[sku_id] = {"count": count, "selected": selected}
#             response = JsonResponse({'code': 0,
#                                      'message': 'OK',
#                                      'cart_sku': {
#                                         "sku_id": sku_id,
#                                         "count": count,
#                                         "selected": selected
#                                       }})
#             saved_data = base64.b64encode(pickle.dumps(cart_data)).decode()
#             response.set_cookie('cart_data', saved_data, max_age=3600*24*14)
#
#             return response
#
#     @staticmethod
#     def delete(request):
#         """从购物车中删除商品"""
#         req_data = json.loads(request.body)
#         sku_id = req_data.get('sku_id')
#
#         if not all([sku_id]):
#             return JsonResponse({'code': 400,
#                                  'message': '缺少必传参数'})
#
#         try:
#             SKU.objects.get(id=sku_id)
#         except Exception:
#             return JsonResponse({'code': 400,
#                                  'message': '商品不存在'})
#
#         user = request.user
#         if user.is_authenticated:
#             # 登录 存储到redis中
#             # 连接redis
#             try:
#                 redis_conn = get_redis_connection('cart')
#             except:
#                 return JsonResponse({'code': 400,
#                                      'message': '连接数据库失败'})
#             try:
#                 redis_conn.hdel(f'cart_{user.id}', sku_id)
#                 if sku_id in redis_conn.smembers:
#                     redis_conn.srem(f'cart_selected_{user.id}', sku_id)
#             except Exception:
#                 return JsonResponse({'code': 400,
#                                      'message': '删除数据失败'})
#
#             return JsonResponse({'code': 0,
#                                  'message': '购物车记录删除成功'})
#
#         else:
#             # 未登录 存储到cookie中
#             # 首先要先获取cookie
#             try:
#                 cart_data_str = request.COOKIES.get('cart_data')
#             except Exception:
#                 return JsonResponse({'code': 400,
#                                      'message': '连接数据库失败'})
#
#             cart_data = pickle.loads(base64.b64decode(cart_data_str))
#
#             # 删除
#             cart_data.pop(sku_id)
#             response = JsonResponse({'code': 0,
#                                     'message': '购物车记录删除成功'})
#             saved_data = base64.b64encode(pickle.dumps(cart_data)).decode()
#             response.set_cookie('cart_data', saved_data, max_age=3600*24*14)
#
#             return response
#
#
# class CartsSelectionView(View):
#     @staticmethod
#     def put(request):
#         """全选或不选购物车商品"""
#         req_data = json.loads(request.body)
#         selected = req_data.get('selected', True) #True False
#
#         # 获取当前登录用户信息
#         user = request.user
#         # 判断是否登录
#         if user.is_authenticated:
#             # 登录 存储到redis中
#             # 连接redis
#             try:
#                 redis_conn = get_redis_connection('cart')
#                 # 不论全选还是不选 都不要操作商品
#                 # 获取所有商品id
#                 # hash filed
#                 cart_skus = redis_conn.hkeys(f'cart_{user.id}')
#                 # 全选
#                 if selected:
#                     redis_conn.sadd(f'cart_selected_{user.id}', *cart_skus)
#                 # 全不选
#                 else:
#                     # 移除 选中的所有id
#                     redis_conn.srem(f'cart_selected_{user.id}', *cart_skus)
#
#             except Exception:
#                 return JsonResponse({'code': 400,
#                                      'message': '连接数据库失败'})
#
#             return JsonResponse({'code': 0,
#                                  'message': 'OK'})
#         else:
#             # 未登录 存储到cookie中
#             # 首先要先获取cookie
#             try:
#                 cart_data_str = request.COOKIES.get('cart_data')
#                 # 获取所有购物车的数据
#                 cart_data = pickle.loads(base64.b64decode(cart_data_str))
#             except Exception:
#                 return JsonResponse({'code': 400,
#                                      'message': '获取购物车数据失败'})
#
#             for cart_sku in cart_data.values():
#                 cart_sku['selected'] = selected #True
#
#             response = JsonResponse({'code': 0,
#                                      'message': 'OK'})
#             saved_data = base64.b64encode(pickle.dumps(cart_data)).decode()
#             response.set_cookie('cart_data', saved_data, max_age=3600*24*14)
#
#             return response

import json
from django.http import JsonResponse
from django.views import View

from carts.utils import CartHelper
from goods.models import SKU


class CartsView(View):
    @staticmethod
    def post(request):
        req_data = json.loads(request.body)
        sku_id = req_data.get('sku_id')
        count = req_data.get('count')
        selected = req_data.get('selected', True)

        if not all([sku_id, count]):
            return JsonResponse({'code': 400,
                                 'message': '缺少必传参数'})

        try:
            count = int(count)
        except:
            return JsonResponse({'code': 400,
                                 'message': 'count参数有误'})

        if count <= 0:
            return JsonResponse({'code': 400,
                                 'message': 'count参数有误'})

        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception:
            return JsonResponse({'code': 400,
                                 'message': 'sku商品不存在'})

        response = JsonResponse({'code': 0,
                                 'message': '购物车添加成功',
                                 'count': count})

        try:
            cart_helper = CartHelper(request, response)
            cart_helper.add_cart(sku_id, count, selected)
        except Exception:
            return JsonResponse({'code': 400,
                                 'message': '购物车添加失败'})

        return response

    @staticmethod
    def get(request):
        try:
            cart_helper = CartHelper(request)
            cart_dict = cart_helper.get_cart()
        except Exception:
            return JsonResponse({'code': 400,
                                 'message': '购物车获取失败'})

        try:
            skus = SKU.objects.filter(id__in=cart_dict.keys())
        except Exception:
            return JsonResponse({'code': 400,
                                 'message': '获取sku商品信息失败'})

        cart_skus = []
        for sku in skus:
            cart_skus.append({
                'id': sku.id,
                'name': sku.name,
                'price': sku.price,
                'default_image_url': 'http://192.168.19.131:8888/' + sku.default_image.name,
                'count': cart_dict[sku.id]['count'],
                'selected': cart_dict[sku.id]['selected']
            })

        return JsonResponse({'code': 0,
                             'message': 'OK',
                             'cart_skus': cart_skus})

    @staticmethod
    def put(request):
        req_data = json.loads(request.body)
        sku_id = req_data.get('sku_id')
        count = req_data.get('count')
        selected = req_data.get('selected', True)

        if not all([sku_id, count]):
            return JsonResponse({'code': 400,
                                 'message': '缺少必传参数'})

        try:
            count = int(count)
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'message': 'count参数有误'})

        if count <= 0:
            return JsonResponse({'code': 400,
                                 'message': 'count参数有误'})

        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'message': 'sku商品不存在'})
            # ② 根据用户是否登录，分别修改购物车记录的数据
        cart_sku = {
            'sku_id': sku_id,
            'count': count,
            'selected': selected
        }

        response = JsonResponse({'code': 0,
                                 'message': '购物车记录修改成功',
                                 'cart_sku': cart_sku})

        try:
            cart_helper = CartHelper(request, response)
            cart_helper.update_cart(sku_id, count, selected)
        except Exception as e:
            return JsonResponse({'code': 400,
                                 'message': '购物车记录修改失败'})

        return response

    @staticmethod
    def delete(request):
        # ① 获取参数并进行校验
        req_data = json.loads(request.body)
        sku_id = req_data.get('sku_id')

        if not sku_id:
            return JsonResponse({'code': 400,
                                 'message': '缺少必传参数'})

        # ② 根据用户是否登录，删除对应的购物车记录
        response = JsonResponse({'code': 0,
                                 'message': '购物车记录删除成功'})

        try:
            cart_helper = CartHelper(request, response)
            cart_helper.remove_cart(sku_id)
        except Exception:
            return JsonResponse({'code': 400,
                                 'message': '购物车记录删除失败'})
        return response


class CartsSelectionView(View):
    @staticmethod
    def put(request):
        # ① 获取参数并进行校验
        req_data = json.loads(request.body)
        selected = req_data.get('selected', True)
        # ② 根据用户是否登录，对购物车记录进行全选和取消全选操作
        response = JsonResponse({'code': 0,
                                 'message': '购物车记录操作成功'})

        try:
            cart_helper = CartHelper(request, response)
            cart_helper.select_cart(selected)
        except Exception:
            return JsonResponse({'code': 400,
                                 'message': '购物车记录操作失败'})

        return response
